package zxj.weixin.mp.service;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import zxj.weixin.mp.api.CardApi;
import zxj.weixin.mp.api.entity.MemberCardUserInfo;
import zxj.weixin.mp.domain.CardBaseInfo;
import zxj.weixin.mp.domain.MemberCard;
import zxj.weixin.mp.domain.vo.MemberCardVO;
import zxj.weixin.mp.mapper.CardBaseInfoMapper;
import zxj.weixin.mp.mapper.MemberCardMapper;
import zxj.weixin.utils.MapUtils;

/**
 * 微信会员卡Service
 * 
 * @author zhuxuejiang
 *
 */
@Service
public class MemberCardService {

	private static final Logger LOGGER = LoggerFactory.getLogger(MemberCardService.class);

	private static final String DATE_TYPE_FIX_TIME_RANGE = "DATE_TYPE_FIX_TIME_RANGE";
	private static final String DATE_TYPE_FIX_TERM = "DATE_TYPE_FIX_TERM";

	@Autowired
	private MemberCardMapper memberCardMapper;

	@Autowired
	private CardBaseInfoMapper cardBaseInfoMapper;

	@Autowired
	private WeixinService weixinService;

	/**
	 * 创建会员卡
	 * 
	 * @param memberCard   微信会员卡实体
	 * @param cardBaseInfo 微信卡券基础信息实体
	 * @throws Exception
	 */
	public void create(MemberCard memberCard, CardBaseInfo cardBaseInfo) throws Exception {
		// 判断memberCard是否为空
		if (null == memberCard) {
			return;
		}

		// 判断cardBaseInfo是否为空
		if (null == cardBaseInfo) {
			return;
		}

		// 判断appId是否为空
		if (StringUtils.isBlank(memberCard.getAppId())) {
			return;
		}

		// 判断accessToken是否为空
		String accessToken = weixinService.getAccessToken(memberCard.getAppId());
		if (null == accessToken) {
			return;
		}

		Map<String, Object> dataMap = this.createMemberCardMap(memberCard, cardBaseInfo);
		LOGGER.debug(MapUtils.map2JsonString(dataMap));

		Map<String, Object> resultMap = CardApi.create(accessToken, dataMap);
		if (null == resultMap) {
			return;
		}

		String cardId = (String) resultMap.get("card_id");
		if (StringUtils.isBlank(cardId)) {
			return;
		}

		// 持久化微信会员卡实体
		memberCard.setCardId(cardId);
		memberCardMapper.insertSelective(memberCard);

		// 持久化微信卡券基础信息实体
		cardBaseInfo.setCardId(cardId);
		cardBaseInfoMapper.insertSelective(cardBaseInfo);
	}

	/**
	 * 查询微信公众号当前可用的会员卡（每个微信公众号只有一个会员卡可用）
	 * 
	 * @param appId 公众号的唯一标识
	 * @return 微信公众号当前可用的会员卡实体
	 */
	public MemberCard findCurrentMemberCard(String appId) {
		MemberCardVO vo = new MemberCardVO();
		vo.setAppId(appId);
		return memberCardMapper.selectObject(vo);
	}

	private Map<String, Object> createMemberCardMap(MemberCard memberCard, CardBaseInfo cardBaseInfo)
			throws IOException {
		// 将MemberCard实体转换为Map。实体中值为null的属性不转换，转换后Map的key为下划线分割规则
		Map<String, Object> memberCardMap = MapUtils
				.keyLowerCamel2LowerUnderScore(MapUtils.object2MapNonNull(memberCard));

		// 将baseInfoMap实体转换为Map。实体中值为null的属性不转换，转换后Map的key为下划线分割规则
		Map<String, Object> baseInfoMap = MapUtils
				.keyLowerCamel2LowerUnderScore(MapUtils.object2MapNonNull(cardBaseInfo));

		// 处理baseInfoMap中和接口数据格式不一致的数据。
		// 此处为方便数据持久化，未将接口中的JSON Object单独放到一个表中存储

		// 处理卡券库存的数量
		Integer quantity = (Integer) baseInfoMap.get("sku_quantity");
		if (null != quantity) {
			Map<String, Integer> skuMap = new HashMap<>(16);
			skuMap.put("quantity", quantity);
			baseInfoMap.put("sku", skuMap);
		}

		baseInfoMap.remove("sku_quantity");

		// 处理使用日期，有效期的信息
		String dateInfoType = (String) baseInfoMap.get("date_info_type");
		if (StringUtils.isNotBlank(dateInfoType)) {
			Map<String, Object> dateInfoMap = new HashMap<>(16);
			dateInfoMap.put("type", baseInfoMap.get("date_info_type"));

			if (dateInfoType.equalsIgnoreCase(DATE_TYPE_FIX_TIME_RANGE)) {
				dateInfoMap.put("begin_timestamp", baseInfoMap.get("begin_timestamp"));
				dateInfoMap.put("end_timestamp", baseInfoMap.get("end_timestamp"));
			} else if (dateInfoType.equalsIgnoreCase(DATE_TYPE_FIX_TERM)) {
				dateInfoMap.put("fixed_term", baseInfoMap.get("fixed_term"));
				dateInfoMap.put("fixed_begin_term", baseInfoMap.get("fixed_begin_term"));
				dateInfoMap.put("end_timestamp", baseInfoMap.get("fixed_end_timestamp"));
			}
			baseInfoMap.put("date_info", dateInfoMap);
		}

		Boolean isSwipeCard = (Boolean) baseInfoMap.get("is_swipe_card");
		if (isSwipeCard) {
			Map<String, Object> swipeCardMap = new HashMap<>(16);
			swipeCardMap.put("is_swipe_card", true);

			Map<String, Object> payInfoMap = new HashMap<>(16);
			payInfoMap.put("swipe_card", swipeCardMap);

			baseInfoMap.put("pay_info", payInfoMap);
		}

		baseInfoMap.remove("date_info_type");
		baseInfoMap.remove("is_swipe_card");
		baseInfoMap.remove("begin_timestamp");
		baseInfoMap.remove("end_timestamp");
		baseInfoMap.remove("fixed_term");
		baseInfoMap.remove("fixed_begin_term");
		baseInfoMap.remove("fixed_end_timestamp");

		baseInfoMap.remove("card_type");
		baseInfoMap.remove("check_state");
		baseInfoMap.remove("refuse_reason");

		memberCardMap.remove("app_id");

		// 以下代码组织接口需要的数据格式
		memberCardMap.put("base_info", baseInfoMap);

		Map<String, Object> customFieldMap = new HashMap<>(16);
		customFieldMap.put("name_type", "FIELD_NAME_TYPE_COUPON");
		customFieldMap.put("url", "http://www.qq.com");
		memberCardMap.put("custom_field1", customFieldMap);

		Map<String, Object> cardMap = new HashMap<>(16);
		cardMap.put("card_type", "MEMBER_CARD");
		cardMap.put("member_card", memberCardMap);

		Map<String, Object> dataMap = new HashMap<>(16);
		dataMap.put("card", cardMap);

		return dataMap;
	}

	/**
	 * 拉取会员信息
	 * 
	 * @param appId        公众号的唯一标识
	 * @param cardId       会员卡ID
	 * @param userCardCode 会员卡号
	 * @return
	 * @throws IOException
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public MemberCardUserInfo getMemberCardUserInfo(String appId, String cardId, String userCardCode)
			throws IOException, Exception {
		Map<String, Object> dataMap = new HashMap<>(16);
		dataMap.put("card_id", cardId);
		dataMap.put("code", userCardCode);

		String accessToken = weixinService.getAccessToken(appId);
		Map<String, Object> map = CardApi.getMemberCardUserInfo(accessToken, dataMap);

		Integer errcode = (Integer) map.get("errcode");
		if (null == map || null == errcode || errcode != 0) {
			return null;
		}

		MemberCardUserInfo memberCardUserInfo = new MemberCardUserInfo();
		memberCardUserInfo.setOpenid((String) map.get("openid"));
		memberCardUserInfo.setNickname((String) map.get("nickname"));
		memberCardUserInfo.setMembershipNumber((String) map.get("membership_number"));
		memberCardUserInfo.setBonus((Integer) map.get("bonus"));
		memberCardUserInfo.setBalance((Double) map.get("balance"));
		memberCardUserInfo.setSex((String) map.get("sex"));
		memberCardUserInfo.setUserCardStatus((String) map.get("user_card_status"));
		memberCardUserInfo.setHasActive((Boolean) map.get("has_active"));

		Map<String, Object> userInfoMap = (Map<String, Object>) map.get("user_info");
		if (null == userInfoMap) {
			return memberCardUserInfo;
		}

		List<Map<String, Object>> commonFieldList = (List<Map<String, Object>>) userInfoMap.get("common_field_list");
		if (null != commonFieldList && commonFieldList.size() > 0) {
			for (Map<String, Object> commonField : commonFieldList) {
				if (null == commonField) {
					continue;
				}

				String name = (String) commonField.get("name");
				String value = (String) commonField.get("value");
				if (null == name) {
					continue;
				}

				if ("USER_FORM_INFO_FLAG_MOBILE".equals(name)) {
					memberCardUserInfo.setMobileCommonField(value);
				} else if ("USER_FORM_INFO_FLAG_NAME".equals(name)) {
					memberCardUserInfo.setNameCommonField(value);
				} else if ("USER_FORM_INFO_FLAG_SEX".equals(name)) {
					memberCardUserInfo.setSexCommonField(value);
				} else if ("USER_FORM_INFO_FLAG_BIRTHDAY".equals(name)) {
					memberCardUserInfo.setBirthdayCommonField(value);
				} else if ("USER_FORM_INFO_FLAG_IDCARD".equals(name)) {
					memberCardUserInfo.setIdcardCommonField(value);
				} else if ("USER_FORM_INFO_FLAG_EMAIL".equals(name)) {
					memberCardUserInfo.setEmailCommonField(value);
				} else if ("USER_FORM_INFO_FLAG_LOCATION".equals(name)) {
					memberCardUserInfo.setLocationCommonField(value);
				} else if ("USER_FORM_INFO_FLAG_INDUSTRY".equals(name)) {
					memberCardUserInfo.setIndustryCommonField(value);
				} else if ("USER_FORM_INFO_FLAG_INCOME".equals(name)) {
					memberCardUserInfo.setIncomeCommonField(value);
				} else if ("USER_FORM_INFO_FLAG_HABIT".equals(name)) {
					memberCardUserInfo.setHabitCommonField(value);
				} else if ("USER_FORM_INFO_FLAG_EDUCATION_BACKGRO".equals(name)) {
					// 此处需注意： 调用“设置开卡字段”接口，设置“USER_FORM_INFO_FLAG_EDUCATION_BACKGRO（教育背景）”，返回错误信息。
					memberCardUserInfo.setEducationBackgroCommonField(value);
				}
			}
		}

		return memberCardUserInfo;
	}

}
